#pragma once
#include <iostream>
#include <utility>
#include "hash_bucket.hpp"

namespace me
{
    template <typename K, typename V>
    class unordered_map
    {
        struct kov
        {
            const K& operator()(const std::pair<K, V>& kv) const
            {
                return kv.first;
            }
        };

        struct hash
        {
            size_t operator()(const K& key) const
            {
                return static_cast<size_t>(key);
            }
        };

        using hash_map = __hash<K, std::pair<const K, V>, kov, hash>;
        using iterator = typename hash_map::iterator;
        using const_iterator = typename hash_map::const_iterator;
    public:
        std::pair<iterator, bool> insert(const std::pair<K, V>& kv)
        {
            return _tables.insert(kv);
        }

        iterator find(const K& key)
        {
            return _tables.find(key);
        }

        size_t erase(const K& key)
        {
            return _tables.erase(key);
        }

        V& operator[](const K& key)
        {
            std::pair<iterator, bool> ret = _tables.insert({key, V()});
            return ret.first->second;
        }
       
        iterator begin() { return _tables.begin(); }
        const_iterator cbegin() const { return _tables.cbegin(); }
        iterator end() { return _tables.end(); }
        const_iterator cend() const { return _tables.cend(); }

    private:
        hash_map _tables;
    };
}